home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Misc / msql-1.0.6 / src / msql / msqld.c < prev    next >
C/C++ Source or Header  |  1995-05-28  |  14KB  |  767 lines

  1. /*
  2. **    msqld.c    - 
  3. **
  4. **
  5. ** Copyright (c) 1993  David J. Hughes
  6. **
  7. ** Permission to use, copy, and distribute for non-commercial purposes,
  8. ** is hereby granted without fee, providing that the above copyright
  9. ** notice appear in all copies and that both the copyright notice and this
  10. ** permission notice appear in supporting documentation.
  11. **
  12. ** This software is provided "as is" without any expressed or implied warranty.
  13. **
  14. ** ID = "$Id:"
  15. **
  16. */
  17.  
  18.  
  19. #include <stdio.h>
  20. #include <fcntl.h>
  21. #include <limits.h>
  22. #include <sys/types.h>
  23. #include <sys/stat.h>
  24. #include <sys/time.h>
  25. #include <sys/socket.h>
  26. #include <netinet/in.h>
  27. #include <arpa/inet.h>
  28. #include <stdlib.h>
  29. #include <varargs.h>
  30.  
  31.  
  32. #include "common/portability.h"
  33.  
  34. #ifdef HAVE_SYS_UN_H
  35. #  include <sys/un.h>
  36. #endif
  37.  
  38. #include <signal.h>
  39. #include <netdb.h>
  40.  
  41. #ifdef HAVE_SELECT_H
  42. #  include <select.h>
  43. #endif
  44.  
  45. #ifdef HAVE_SYS_SELECT_H
  46. #  include <sys/select.h>
  47. #endif
  48.  
  49. #include "common/site.h"
  50. #include "common/debug.h"
  51.  
  52. #include "msql_priv.h"
  53. #include "errmsg.h"
  54.  
  55.  
  56.  
  57.  
  58. extern  char    *yytext;
  59. extern    int    yylineno;
  60. extern    int    yydebug;
  61. extern    int    titleFlag;
  62.  
  63. extern    char    errMsg[];
  64.  
  65. int    curSock,
  66.     IPsock,
  67.     UNIXsock,
  68.     numCons;
  69.  
  70. #define MAX_SOCK_NUM    100
  71.  
  72. cinfo_t    conArray[MAX_SOCK_NUM];
  73.  
  74. extern    char    *packet;
  75. char    PROGNAME[] = "msqld",
  76.     BLANK_ARGV[] = "                                                  ";
  77.  
  78. #define safeFree(x)  { if(x){ (void)free(x); x = NULL; } }
  79.  
  80.  
  81. void sigTrap(sig)
  82.     int    sig;
  83. {
  84.     int    clientSock;
  85.  
  86.     fprintf(stderr,"\nHit by a sig %d\n\n",sig);
  87.     clientSock = 3;
  88.     printf("\n\nForced server shutdown due to bad signal!\n\n");
  89.     while(clientSock < MAX_SOCK_NUM)
  90.     {
  91.         if (conArray[clientSock].db)
  92.         {
  93.             printf("Forcing close on Socket %d\n",clientSock);
  94.             shutdown(clientSock,2);
  95.             close(clientSock);
  96.         }
  97.         clientSock++;
  98.     }
  99.     shutdown(IPsock,2);
  100.     close(IPsock);
  101. #ifdef HAVE_SYS_UN_H
  102.     shutdown(UNIXsock,2);
  103.     close(UNIXsock);
  104.     unlink(MSQL_UNIX_ADDR);
  105. #endif
  106.     printf("\n");
  107.     abort();
  108. }
  109.  
  110.  
  111. sendError(fd,err)
  112.     char    *err;
  113. {
  114. #    ifdef DEBUG
  115.         printf("Send error called\n");
  116. #    endif
  117.     if (err)
  118.         sprintf(packet,"-1:%s\n",err);
  119.     else
  120.         sprintf(packet,"-1:%s\n",errMsg);
  121.     writePkt(fd);
  122. }
  123.  
  124. sendOK(fd)
  125. {
  126. #    ifdef DEBUG
  127.         printf("Send OK called\n");
  128. #    endif
  129.     sprintf(packet,"1:\n");
  130.     writePkt(fd);
  131. }
  132.  
  133.  
  134. /****************************************************************************
  135. **     _initServer
  136. **
  137. **    Purpose    : 
  138. **    Args    : 
  139. **    Returns    : 
  140. **    Notes    : 
  141. */
  142.  
  143. initServer()
  144. {
  145.     int    sock,
  146.         tcpPort,
  147.         addrLen;
  148.     struct    sockaddr_in    IPaddr;
  149.     struct    servent        *serv_ptr;
  150.     char    *unixPort,
  151.         *envVar;
  152.  
  153. #ifdef HAVE_SYS_UN_H
  154.     struct    sockaddr_un    UNIXaddr;
  155. #endif
  156.  
  157.     /*
  158.     ** Create an IP socket
  159.     */
  160.     tcpPort = MSQL_PORT;
  161.     if ((serv_ptr = getservbyname("msql", "tcp")))
  162.     {
  163.         tcpPort = serv_ptr->s_port;
  164.     }
  165.     if ((envVar = getenv("MSQL_TCP_PORT")))
  166.     {
  167.         tcpPort = atoi(envVar);
  168.     }
  169.     msqlDebug(MOD_GENERAL,"IP Socket is %d\n",tcpPort);
  170.     IPsock = socket(AF_INET, SOCK_STREAM, 0);
  171.     if (IPsock < 0)
  172.     {
  173.         perror("Can't start server : IP Socket ");
  174.         exit(1);
  175.     }
  176.     (void)bzero(&IPaddr, sizeof(IPaddr));
  177.     IPaddr.sin_family = AF_INET;
  178.     IPaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  179.     IPaddr.sin_port = htons(tcpPort);
  180.     if (bind(IPsock, (struct sockaddr *)&IPaddr, sizeof(IPaddr)) < 0)
  181.     {
  182.         perror("Can't start server : IP Bind ");
  183.         exit(1);
  184.     }
  185.     listen(IPsock,5);
  186.  
  187. #ifdef HAVE_SYS_UN_H
  188.     /*
  189.     ** Create the UNIX socket
  190.     */
  191.     unixPort = MSQL_UNIX_ADDR;
  192.     if ((envVar = getenv("MSQL_UNIX_PORT")))
  193.     {
  194.         unixPort = envVar;
  195.     }
  196.     
  197.     msqlDebug(MOD_GENERAL,"UNIX Socket is %s\n",unixPort);
  198.     UNIXsock = socket(AF_UNIX, SOCK_STREAM, 0);
  199.     if (UNIXsock < 0)
  200.     {
  201.         perror("Can't start server : UNIX Socket ");
  202.         exit(1);
  203.     }
  204.     (void)bzero(&UNIXaddr, sizeof(UNIXaddr));
  205.     UNIXaddr.sun_family = AF_UNIX;
  206.     strcpy(UNIXaddr.sun_path, unixPort);
  207.     unlink(unixPort);
  208.     if (bind(UNIXsock, (struct sockaddr *)&UNIXaddr, sizeof(UNIXaddr)) < 0)
  209.     {
  210.         perror("Can't start server : UNIX Bind ");
  211.         exit(1);
  212.     }
  213.     listen(UNIXsock,5);
  214. #endif
  215. }
  216.  
  217.  
  218.  
  219. RETSIGTYPE puntServer(sig)
  220.     int    sig;
  221. {
  222.     int    clientSock;
  223.  
  224.     clientSock = 3;
  225.     if (sig == -1)
  226.     {
  227.         printf("\n\nNormal Server shutdown!\n\n");
  228.     }
  229.     else
  230.     {
  231.         printf("\n\nServer Aborting!\n\n");
  232.     }
  233.     while(clientSock < MAX_SOCK_NUM)
  234.     {
  235.         if (conArray[clientSock].db)
  236.         {
  237.             printf("Forcing close on Socket %d\n",clientSock);
  238.             shutdown(clientSock,2);
  239.             close(clientSock);
  240.         }
  241.         clientSock++;
  242.     }
  243.     shutdown(IPsock,2);
  244.     close(IPsock);
  245.  
  246. #ifdef HAVE_SYS_UN_H
  247.     shutdown(UNIXsock,2);
  248.     close(UNIXsock);
  249.     unlink(MSQL_UNIX_ADDR);
  250. #endif
  251.     printf("\n");
  252.     dropCache();
  253.  
  254.     if (debugSet(MOD_MALLOC))
  255.     {
  256.         fprintf(stderr,"\n\nmalloc() leak detection .....\n");
  257.         checkBlocks(MALLOC_BLK);
  258.     }
  259.     if (debugSet(MOD_MMAP))
  260.     {
  261.         fprintf(stderr,"\n\nmmap() leak detection .....\n");
  262.         checkBlocks(MMAP_BLK);
  263.     }
  264.     printf("\n\nmSQL Daemon Shutdown Complete.\n\n");
  265.     if (sig >= 0)
  266.     {
  267.         exit(1);
  268.     }
  269. }
  270.  
  271.  
  272.  
  273. yyerror(s)
  274.         char    *s;
  275. {
  276.      sprintf(packet,"-1:%s near \"%s\"\n", s, yytext?yytext:"");
  277.     writePkt(curSock);
  278.     msqlClean();
  279. }
  280.  
  281.  
  282.  
  283.  
  284.  
  285. static int curComSock;
  286. static fd_set *clientFdSet;
  287.  
  288. static setConnectionState(sock, fds)
  289.     int    sock;
  290.     fd_set    *fds;
  291. {
  292.     curComSock = sock;
  293.     clientFdSet = fds;
  294. }
  295.  
  296.  
  297. RETSIGTYPE puntClient(sig)
  298.     int    sig;
  299. {
  300.     if (clientFdSet)
  301.     {
  302.         FD_CLR(curComSock, clientFdSet);
  303.         shutdown(curComSock,2);
  304.         close(curComSock);
  305.         if (conArray[curComSock].db)
  306.         {
  307.             safeFree(conArray[curComSock].db);
  308.             safeFree(conArray[curComSock].host);
  309.             safeFree(conArray[curComSock].user);
  310.         }
  311.         conArray[curComSock].db = NULL;
  312.         printf("Forced close of client on socket %d due to pipe sig\n",
  313.             curComSock);
  314.         numCons--;
  315.     }
  316. }
  317.  
  318.  
  319. char    *Arg0;
  320.  
  321. void setProcTitle(va_alist)
  322.         va_dcl
  323. {
  324.     va_list args;
  325.     char    msg[1024],
  326.         *fmt;
  327.     int     module;
  328.  
  329.     if (!titleFlag)
  330.         return;
  331.     va_start(args);
  332.     fmt = (char *)va_arg(args, char *);
  333.     if (!fmt)
  334.         return;
  335.     strcpy(msg,"mSQL : ");
  336.     (void)vsprintf(msg + strlen(msg),fmt,args);
  337.     va_end(args);
  338.     if (strlen(msg) > 50)
  339.     {
  340.         *(msg+50) = 0;
  341.     }
  342.     strcpy(Arg0,BLANK_ARGV);
  343.     strcpy(Arg0,msg);
  344. }
  345.  
  346. initProcTitle(argv)
  347.     char    *argv[];
  348. {
  349.     
  350.     if (!titleFlag)
  351.         return;
  352.     Arg0 = argv[0];
  353.     setProcTitle("Starting");
  354.  
  355. setupSignals()
  356. {
  357. #ifdef SIGSEGV
  358.     signal(SIGSEGV,sigTrap);
  359. #endif
  360. #ifdef SIGBUS
  361.     signal(SIGBUS,sigTrap);
  362. #endif
  363. #ifdef SIGINT
  364.     signal(SIGINT,puntServer);
  365. #endif
  366. #ifdef SIGQUIT
  367.     signal(SIGQUIT,puntServer);
  368. #endif
  369. #ifdef SIGKILL
  370.     signal(SIGKILL,puntServer);
  371. #endif
  372. #ifdef SIGPIPE
  373.     signal(SIGPIPE,puntClient);
  374. #endif
  375. }
  376.  
  377.  
  378.  
  379. main(argc,argv)
  380.     int    argc;
  381.     char    *argv[];
  382. {
  383.     fd_set    readFDs,
  384.         clientFDs;
  385.     int    sock,
  386.         newSock,
  387.         comSock,
  388.         command,
  389.         opt,
  390.         sig,
  391.         error;
  392.     char    dbname[30],
  393.         *uname,
  394.         *cp,
  395.         *prog,
  396.         *arg,
  397.         path[255];
  398.     FILE    *pidFile;
  399.  
  400.     /*
  401.     ** See if we have to re-exec ourselves for procTitle space
  402.     */
  403.     if (titleFlag)
  404.     {
  405.         if (*argv[0] != ' ')
  406.         {
  407.             prog = argv[0];
  408.             argv[0] = BLANK_ARGV;
  409.             execvp(prog,argv,argc);
  410.             perror("Exec failed");
  411.             exit(1);
  412.         }
  413.     }
  414.  
  415.  
  416.     /*
  417.     ** We have enough space for fiddling with the argv, continue
  418.     */
  419.     msqlHomeDir = (char *)getenv("MSQL_HOME");
  420.     if (!msqlHomeDir)
  421.     {
  422.         msqlHomeDir = INST_DIR;
  423.     }
  424.     umask(0);
  425.     numCons=0;
  426.     chdir(msqlHomeDir);
  427.     initDebug();
  428.     initNet();
  429.     initServer();
  430.     initBackend();
  431.     initProcTitle(argv);
  432.     (void)sprintf(path,"%s/msqld.pid",PID_DIR);
  433.     pidFile = fopen(path,"w");
  434.     if (!pidFile)
  435.     {
  436.         perror("Couldn't open PID file");
  437.     }
  438.     else
  439.     {
  440.         fprintf(pidFile,"%d",getpid());
  441.         fclose(pidFile);
  442.     }
  443.     chmod(path,0744);
  444.     umask(0);
  445.     setupSignals();
  446.     msqlLoadAcl(1);
  447.     (void)bzero(&clientFDs,sizeof(fd_set));
  448.     msqlDebug(MOD_GENERAL,"miniSQL debug mode.  Waiting for connections.\n");
  449.     while(1)
  450.     {
  451.         (void)bzero(&readFDs,sizeof(fd_set));
  452.         (void)bcopy(&clientFDs,&readFDs,sizeof(fd_set));
  453.         FD_SET(IPsock,&readFDs);
  454. #ifdef HAVE_SYS_UN_H
  455.         FD_SET(UNIXsock,&readFDs);
  456. #endif
  457.         setProcTitle("Idle - %d clients",numCons);
  458.         if(select(MAX_SOCK_NUM+1,&readFDs,0,0,0) < 0)
  459.             continue;
  460.  
  461.         /*
  462.         ** Is this a new connection request
  463.         */
  464.  
  465.         sock = 0;
  466.         if (FD_ISSET(IPsock,&readFDs))
  467.         {
  468.             sock = IPsock;
  469.         }
  470. #ifdef HAVE_SYS_UN_H
  471.         if (FD_ISSET(UNIXsock,&readFDs))
  472.         {
  473.             sock = UNIXsock;
  474.         }
  475. #endif
  476.         if (sock)
  477.         {
  478.             struct    sockaddr_in cAddr;
  479.             int    cAddrLen;
  480.  
  481.             cAddrLen = sizeof(struct sockaddr_in);
  482.             newSock = accept(sock, (struct sockaddr *)&cAddr, 
  483.                 &cAddrLen);
  484.             if(newSock < 0)
  485.             {
  486.                 perror("Error in accept ");
  487.                 continue;
  488.             }
  489.             if (conArray[newSock].db)
  490.             {
  491.                 safeFree(conArray[newSock].db);
  492.                 safeFree(conArray[newSock].host);
  493.                 safeFree(conArray[newSock].user);
  494.                 conArray[newSock].db = NULL;
  495.             }
  496.  
  497.             /*
  498.             ** Are we over the connection limit
  499.             */
  500.             numCons++;
  501.             if (numCons > MAX_CON)
  502.             {
  503.                 numCons--;
  504.                 sendError(newSock,CON_COUNT_ERROR);
  505.                 shutdown(newSock,2);
  506.                 close(newSock);
  507.                 continue;
  508.             }
  509.  
  510.  
  511.             /*
  512.             ** store the connection details
  513.             */
  514.  
  515.             msqlDebug(MOD_GENERAL,"New connection received on %d\n",
  516.                 newSock);
  517.             error = 0;
  518.             if (sock == IPsock)
  519.             {
  520.                 int    addrLen;
  521.                 struct    hostent *hp;
  522.  
  523.                 addrLen = sizeof(struct sockaddr);
  524.                 getpeername(newSock, (struct sockaddr *)
  525.                     &conArray[newSock].remote, &addrLen);
  526.                 addrLen = sizeof(struct sockaddr);
  527.                 getsockname(newSock, (struct sockaddr *)
  528.                     &conArray[newSock].local, &addrLen);
  529.                 hp = (struct hostent *)gethostbyaddr(
  530.                     (char *)&conArray[newSock].remote.sin_addr,
  531.                     sizeof(conArray[newSock].remote.sin_addr),
  532.                     AF_INET);
  533.                 if (!hp)
  534.                 {
  535.                     sendError(newSock, BAD_HOST_ERROR);
  536.                     error = 1;
  537.                     shutdown(newSock,2);
  538.                     close(newSock);
  539.                     
  540.                 }
  541.                 else
  542.                 {
  543.                     conArray[newSock].host = (char *)
  544.                         strdup(hp->h_name);
  545.                     msqlDebug(MOD_GENERAL,"Host = %s\n",
  546.                         hp->h_name);
  547.                 }
  548.             }
  549.             else
  550.             {
  551.                 conArray[newSock].host = NULL;
  552.                 bzero(&conArray[newSock].local,
  553.                     sizeof(struct sockaddr));
  554.                 bzero(&conArray[newSock].
  555.                     remote,sizeof(struct sockaddr));
  556.                 msqlDebug(MOD_GENERAL,"Host = UNIX domain\n");
  557.             }
  558.  
  559.             if (!error)
  560.             {
  561.                 opt=1;
  562.                 setsockopt(newSock,SOL_SOCKET,SO_KEEPALIVE,
  563.                     (char *) &opt, sizeof(opt));
  564.                 sprintf(packet,
  565.                     "0:%d:%s\n",
  566.                     PROTOCOL_VERSION,SERVER_VERSION);
  567.                 writePkt(newSock);
  568.                 if (readPkt(newSock) <=0)
  569.                 {
  570.                     sendError(newSock,HANDSHAKE_ERROR);
  571.                     shutdown(newSock,2);
  572.                     close(newSock);
  573.                     conArray[newSock].host = NULL;
  574.                                     bzero(&conArray[newSock].local,
  575.                                             sizeof(struct sockaddr));
  576.                                     bzero(&conArray[newSock].
  577.                                             remote,sizeof(struct sockaddr));
  578.  
  579.                 }
  580.                 else
  581.                 {
  582.                     FD_SET(newSock,&clientFDs);
  583.                     uname = (char *)strtok(packet,"\n");
  584.                     msqlDebug(MOD_GENERAL,"User = %s\n",uname);
  585.                     conArray[newSock].user = (char *)
  586.                         strdup(uname);
  587.                     sprintf(packet,"-100:\n");
  588.                     writePkt(newSock);
  589.                 }
  590.             }
  591.             continue;
  592.         }
  593.  
  594.     
  595.  
  596.         /*
  597.         ** This must be a command.
  598.         */    
  599.  
  600.         comSock = 3;
  601.         while(comSock < MAX_SOCK_NUM)
  602.         {
  603.             if (FD_ISSET(comSock,&readFDs))
  604.             {
  605.             setConnectionState(comSock,&clientFDs);
  606.             if (readPkt(comSock) <= 0)
  607.                 command = QUIT;
  608.             else
  609.                 command = atoi(packet);
  610.             msqlDebug(MOD_GENERAL,"Command on sock %d = %d (%s)\n",
  611.                 comSock, command, comTable[command]);
  612.             switch(command)
  613.             {
  614.                 case INIT_DB:
  615.                 setProcTitle("Init DB");
  616.                 cp=(char *)strtok(packet+2,"\n\r");
  617.                 strcpy(dbname,cp);
  618.                 msqlDebug(MOD_GENERAL,"DBName = %s\n", dbname);
  619.                 conArray[comSock].access = msqlCheckAccess(
  620.                     dbname, conArray + comSock);
  621.                 if(conArray[comSock].access == NO_ACCESS)
  622.                 {
  623.                     sendError(comSock, 
  624.                         ACCESS_DENIED_ERROR);
  625.                     break;
  626.                 }
  627.                 if (msqlInit(dbname) < 0)
  628.                 {
  629.                     sendError(comSock,NULL);
  630.                 }
  631.                 else
  632.                 {
  633.                     sendOK(comSock);
  634.                     conArray[comSock].db =
  635.                         (char *)strdup(dbname);
  636.                     msqlSetDB(dbname);
  637.                 }
  638.                 break;
  639.  
  640.                 case QUERY:
  641.                 if (!conArray[comSock].db)
  642.                 {
  643.                     sendError(comSock,NO_DB_ERROR);
  644.                     break;
  645.                 }
  646.                 curSock = comSock;
  647.                 cp=(char *)(packet+2);
  648.                 arg = (char *)strdup(cp);
  649.                 if (debugSet(MOD_QUERY))
  650.                     fprintf(stderr,"\n");
  651.                 msqlDebug(MOD_QUERY,"Query = %s",arg);
  652.                 msqlSetDB(conArray[comSock].db);
  653.                 msqlSetPerms(conArray[comSock].access);
  654.                 msqlParseQuery(arg,comSock);
  655.                 safeFree(arg);
  656.                 break;
  657.  
  658.                 case DB_LIST:
  659.                 setProcTitle("DB List");
  660.                 curSock = comSock;
  661.                 msqlListDBs(comSock);
  662.                 break;
  663.  
  664.                 case TABLE_LIST:
  665.                 setProcTitle("Table List");
  666.                 if (!conArray[comSock].db)
  667.                 {
  668.                     sendError(comSock, NO_DB_ERROR);
  669.                     break;
  670.                 }
  671.                 curSock = comSock;
  672.                 msqlListTables(comSock,conArray[comSock].db);
  673.                 break;
  674.  
  675.                 case FIELD_LIST:
  676.                 setProcTitle("Field List");
  677.                 if (!conArray[comSock].db)
  678.                 {
  679.                     sendError(comSock,NO_DB_ERROR);
  680.                     break;
  681.                 }
  682.                 cp=(char *)strtok(packet+2,
  683.                     "\n\r");
  684.                 arg = (char *)strdup(cp);
  685.                 curSock = comSock;
  686.                 msqlListFields(comSock,
  687.                     arg,conArray[comSock].db);
  688.                 break;
  689.  
  690.                 case QUIT:
  691.                 msqlDebug(MOD_GENERAL,"DB QUIT!\n");
  692.                 FD_CLR(comSock,&clientFDs);
  693.                 shutdown(comSock,2);
  694.                 close(comSock);
  695.                 if (conArray[comSock].db)
  696.                 {
  697.                    safeFree(conArray[comSock].db);
  698.                    safeFree(conArray[comSock].host);
  699.                    safeFree(conArray[comSock].user);
  700.                 }
  701.                 conArray[comSock].db = NULL;
  702.                 numCons--;
  703.                 break;
  704.         
  705.                 case CREATE_DB:
  706.                 setProcTitle("Create DB");
  707.                 if (!msqlCheckLocal(conArray + comSock))
  708.                 {
  709.                     sendError(comSock,PERM_DENIED_ERROR);
  710.                     break;
  711.                 }
  712.                 cp=(char *)strtok(packet+2,
  713.                     "\n\r");
  714.                 arg = (char *)strdup(cp);
  715.                 msqlCreateDB(comSock,arg);
  716.                 break;
  717.  
  718.                 case DROP_DB:    
  719.                 setProcTitle("Drop DB");
  720.                 if (!msqlCheckLocal(conArray + comSock))
  721.                 {
  722.                     sendError(comSock,PERM_DENIED_ERROR);
  723.                     break;
  724.                 }
  725.                 cp=(char *)strtok(packet+2,
  726.                     "\n\r");
  727.                 arg = (char *)strdup(cp);
  728.                 msqlDropDB(comSock,arg);
  729.                 break;
  730.  
  731.                 case RELOAD_ACL:
  732.                 setProcTitle("Reload ACL");
  733.                 if (!msqlCheckLocal(conArray + comSock))
  734.                 {
  735.                     sendError(comSock,PERM_DENIED_ERROR);
  736.                     break;
  737.                 }
  738.                 (void)sprintf(packet,"-100:\n");
  739.                 reloadAcls(comSock);
  740.                 writePkt(comSock);
  741.                 break;
  742.  
  743.                 case SHUTDOWN:
  744.                 setProcTitle("Shutdown");
  745.                 if (!msqlCheckLocal(conArray + comSock))
  746.                 {
  747.                     sendError(comSock,PERM_DENIED_ERROR);
  748.                     break;
  749.                 }
  750.                 sprintf(packet,"-100:\n");
  751.                 writePkt(comSock);
  752.                 puntServer(-1);
  753.                 exit(0);
  754.                 break;
  755.  
  756.                 default:
  757.                 sendError(comSock, UNKNOWN_COM_ERROR);
  758.                 break;
  759.             }
  760.             msqlDebug(MOD_GENERAL,"Command Processed!\n");
  761.             }
  762.             comSock++;
  763.         }
  764.     }
  765. }
  766.